﻿// Copyright (c) 2012 - 2021 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2021-03-19 version 4.0.0 Jared Zheng <jaredz at outlook dot com>

#ifndef __SERVER_INFO_H__
#define __SERVER_INFO_H__

#pragma once

#include "CommonDefine.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 服务信息结构方法定义, 粗略统计使用, 未做多线程数据保护
struct tagSERVER_INFO : public tagSERVER_STATUS
{
public:
    tagSERVER_INFO(void);
    ~tagSERVER_INFO(void);

    size_t Length(UShort us = (UShort)SERVERU_SYNC_ALL);

    // 按特定状态要求读写
    void   Status(CStream& Stream, UShort us = (UShort)SERVERU_SYNC_ALL);
    // 按特定状态要求读写
    void   Info(CStream& Stream, UShort us = (UShort)SERVERU_SYNC_ALL);
    // 拷贝数据
    void   Copy(const tagSERVER_STATUS& ss);

    // 增加连接量
    void   IncrTotal(bool bLoad = true, UInt uIncr = 1);
    // 减少连接量
    void   DecrTotal(bool bLoad = true, UInt uDecr = 1);
    // 增加有效量
    void   IncrOnline(bool bLoad = false, UInt uIncr = 1);
    // 减少有效量
    void   DecrOnline(bool bLoad = false, UInt uDecr = 1);
    // 连接量和有效量及负载状态清零
    void   Zero(void);
    // 重置所有数据
    void   Reset(void);

    // 设置同步状态
    void   SetUpdate(UShort us = (UShort)SERVERU_SYNC);

    // 有效量[连接量]清零
    void   ClearOnline(bool bTotal = true);
    // 解除告警或者异常状态
    void   Clear(bool bTotal = true);
    // 清除正常负载
    void   ClearLoad(void);

    // 设置繁忙状态
    void   SetBusyLoad(void);
    // 设置满载状态
    void   SetFullLoad(void);
    // 设置超负荷状态
    void   SetOverLoad(void);
    // 设置告警状态
    void   SetWarnLoad(void);
    // 设置异常状态
    void   SetMayDay(void);

    // 判断是否繁忙
    bool   IsBusyLoad(bool bExact = true);
    // 判断是否满载
    bool   IsFullLoad(bool bExact = true);
    // 判断是否超负荷
    bool   IsOverLoad(bool bExact = true);
    // 判断是否告警
    bool   IsWarnLoad(bool bExact = true);
    // 判断是否异常
    bool   IsMayDay(void);

    // 判断是否有过更新
    bool   IsUpdated(void);
public:
    UInt       uSync;       // (1 << COMMON_RANK_ENUM)的组合, 表示同步其他服务的标志位
    CStrAddr   StrAddr;     // 额外的地址信息
    CString    strRoutine;  // 额外的业务附加数据
    CString    strInstance; // 额外的业务附加数据
};
typedef tagSERVER_INFO SERVER_INFO, *PSERVER_INFO;

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// tagSERVER_DATA : 服务信息数据
struct tagSERVER_DATA : public tagSERVER_INFO
{
public:
    tagSERVER_DATA(void);
    ~tagSERVER_DATA(void);

    void   ResetData(void);
public:
    Int        nStatus; // 服务状态SERVER_STATUS_ENUM
    UInt       uRank;   // 服务的层级编号
    UInt       uQCheck; // 事件队列的存活检测时间queue-check time[S]
    Socket_t   sListen; // 监听
    Socket_t   sConnect[COMMONR_MAX]; // 链接其他服务
    Int        nLink[COMMONR_MAX];    // 链接其他服务状态SERVER_LINK_ENUM

};
typedef tagSERVER_DATA SERVER_DATA, *PSERVER_DATA;

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 服务信息集群结构定义
typedef CTMap<ULLong, SERVER_INFO>          MAP_INFO;
typedef CTMap<ULLong, SERVER_INFO>::PAIR    PAIR_INFO;

struct tagSERVER_CLUSTER : public MObject
{
public:
    tagSERVER_CLUSTER(void);
    ~tagSERVER_CLUSTER(void);

    // 服务集群增加
    void Link(const tagSERVER_STATUS& ss);
    // 服务集群更新
    void Update(const tagSERVER_STATUS& ssIncr, const tagSERVER_STATUS& ssDecr);
    // 服务集群减少
    void Unlink(const tagSERVER_STATUS& ss);
    // 设置同步状态
    void SetUpdate(UShort us = (UShort)SERVERU_SYNC);
    // 重置数据
    void Reset(void);
public:
    // 更新SERVERU_LINK&SERVERU_SYNC为SERVERU_OKAY状态, SERVERU_UNLINK状态删除
    void Update(void);
    // 按特定状态要求读取服务数据
    bool Read(CStream& Stream, UShort us = (UShort)SERVERU_SYNC_ALL);
    // 按特定状态要求写入服务数据
    bool Write(PAIR_INFO* pPair, CStream& Stream, UShort us = (UShort)SERVERU_SYNC_ALL);
    // 检测写入数据是否超过流的剩余缓存, 超过返回false, 否则写入数据, index跳转到下一个
    bool CheckWrite(UInt& uCount, PINDEX& index, CStream& Stream, UShort us = (UShort)SERVERU_SYNC_ALL);
public:
    SERVER_STATUS   Status;
public:
    MAP_INFO    Info;
    CSyncLock   Lock;
};
typedef struct tagSERVER_CLUSTER SERVER_CLUSTER, *PSERVER_CLUSTER;

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 服务信息同步结构定义
typedef CTArray<Socket_t>                   ARY_SYNC;

struct tagSERVER_SYNC : public MObject
{
public:
    tagSERVER_SYNC(void);
    ~tagSERVER_SYNC(void);

    bool AddSync(Socket_t sSocket);
    bool RemoveSync(Socket_t sSocket);

    bool GetSync(ARY_SYNC& aSync);

    void Reset(void);
public:
    ARY_SYNC    Sock;
    CSyncLock   Lock;
};
typedef struct tagSERVER_SYNC SERVER_SYNC, *PSERVER_SYNC;

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 服务信息交换链定义
template <typename TCHAIN>
struct tagSERVER_CHAIN : public MObject
{
public:
    tagSERVER_CHAIN(void);
    ~tagSERVER_CHAIN(void);

    void      Init(Int nHashSize = CContainerTraits::HASHD_SIZE);
    void      Exit(void);

    TCHAIN&   GetClone(void);
    TCHAIN&   GetCurr(void);
    TCHAIN&   GetNext(void);

    void      Swap(void);
public:
    UInt        uIndex;
    TCHAIN      Chain[2];
    CSyncLock   Lock;
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "ServerInfo.inl"

#endif // __SERVER_INFO_H__
